package haizhi.fruitmall.action;

import haizhi.fruitmall.constant.PageInfoMsg;
import haizhi.fruitmall.constant.ResultConstant;
import haizhi.fruitmall.constant.RoleMsg;
import haizhi.fruitmall.constant.UserDetailedMsg;
import haizhi.fruitmall.constant.UserMsg;
import haizhi.fruitmall.constant.UserRoleMsg;
import haizhi.fruitmall.pojo.po.User;
import haizhi.fruitmall.pojo.po.UserDetailed;
import haizhi.fruitmall.pojo.po.UserRole;
import haizhi.fruitmall.query.PageResult;
import haizhi.fruitmall.service.RoleService;
import haizhi.fruitmall.service.UserService;
import haizhi.fruitmall.util.DateUtil;
import haizhi.fruitmall.util.EncryptionUtil;
import haizhi.fruitmall.util.RandomUtils;
import haizhi.fruitmall.util.UserValidate;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageInfo;

@Controller
@RequestMapping("/user")
public class UserController {

	@Autowired
	private UserService userService;

	@Autowired
	private RoleService roleService;

	/**
	 * 添加用户
	 * @param map
	 * @return
	 */
	/* @RequiresPermissions("user:add") */
	@RequestMapping(value = "/addUser", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map addUser(@RequestBody Map map) {
		Map messages = new HashMap();
		// 获取注册信息
		String user_name = (String) map.get(UserMsg.USER_NAME);// 用户名
		String user_password = (String) map.get(UserMsg.USER_PASSWORD);// 用户密码
		String user_real_name = (String) map
				.get(UserDetailedMsg.USER_REAL_NAME);// 用户真实姓名
		String user_tel = (String) map.get(UserDetailedMsg.USER_TEL);// 手机号码
		String user_register_time = DateUtil.formatDateByFormat(new Date(),
				DateUtil.DATE_FORMAT);// 用户注册时间

		// 用户名不能为空
		if (UserValidate.isNull(user_name)) {
			messages.put(ResultConstant.RESULT, UserMsg.USER_NAME_NOTNULL);
			return messages;
		}

		// 判断用户名格式是否正确（必须包含字母和数字）
		if (!UserValidate.isNumericAndLetter(user_name)) {
			messages.put(ResultConstant.RESULT, UserMsg.USERNAME_FORMAT_ERROR);
			return messages;
		}

		// 判断用户名是否存在
		List<User> userList = userService.getUserByUserName(user_name);
		if (userList.size() > 0) {
			messages.put(ResultConstant.RESULT, UserMsg.USER_EXIST);
			return messages;
		}

		// 密码不能为空
		if (UserValidate.isNull(user_password)) {
			messages.put(ResultConstant.RESULT, UserMsg.USER_PASSWORD_NOTNULL);
			return messages;
		}

		// 密码格式错误(密码只能使用英文字母、数字以及-和_，并且首字符必须为字母或数字 密码首字符必须为字母或数字)
		if (!UserValidate.checkUserNamePassword(user_password)) {
			messages.put(ResultConstant.RESULT, UserMsg.PASSWORD_FORMAT_ERROR);
			return messages;
		}

		// 判断密码长度(6-20之间)
		if (!UserValidate.isLengthRequired(UserMsg.PASSWORD_MIN_LENGTH,
				UserMsg.PASSWORD_MAX_LENGTH, user_password)) {
			messages.put(ResultConstant.RESULT, UserMsg.PASSWORD_LENGTH_ERROR);
			return messages;
		}

		// 手机号码判空
		if (UserValidate.isNull(user_tel)) {
			messages.put(ResultConstant.RESULT,
					UserDetailedMsg.USER_TEL_NOTNULL);
			return messages;
		}

		// 手机号码格式不正确
		if (!UserValidate.isHandset(user_tel)) {
			messages.put(ResultConstant.RESULT,
					UserDetailedMsg.TEL_FORMAT_ERROR);
			return messages;
		}

		// 判断手机号是否被注册
		Map userTelConditionMap = new HashMap();
		userTelConditionMap.put(UserDetailedMsg.USER_TEL, user_tel);
		List<UserDetailed> userDetaileds = userService
				.getUserDetailedByCondition(userTelConditionMap);
		if (userDetaileds.size() > 0) {
			messages.put(ResultConstant.RESULT, UserDetailedMsg.USER_TEL_EXIST);
			return messages;
		}

		// 为新增用户添加用户编号
		Integer user_id = Integer.parseInt(RandomUtils.generateNum(9));
		while (userService.findUserById(user_id) != null) {
			user_id = Integer.parseInt(RandomUtils.generateNum(9));
		}

		// 添加用户基本信息
		User user = new User();
		user.setUserId(user_id);
		user.setUserName(user_name);
		user.setUserPassword(EncryptionUtil.getEncryption(user_password,
				user_name, 1024));// 密码加密
		user.setUserHeadPath(UserMsg.USER_DEFAULT_HEAD_PATH);
		userService.insertUser(user);

		// 添加用户详细信息
		UserDetailed userDetailed = new UserDetailed();
		userDetailed.setUserId(user_id);
		userDetailed.setRealName(user_real_name);
		userDetailed.setRegisterTime(user_register_time);
		userDetailed.setUserTel(user_tel);
		userService.insertUserDetailed(userDetailed);

		// 添加默认用户角色
		map.put(UserMsg.USER_ID, user_id);
		List<Map<String, Integer>> urList = new ArrayList<Map<String, Integer>>();
		Map<String, Integer> urMap = new HashMap<String, Integer>();
		urMap.put(RoleMsg.ROLE_ID, RoleMsg.DEFAULT_ROLE_ID);
		urList.add(urMap);
		map.put(UserRoleMsg.USER_ROLE, urList);
		addRoleForUser(map);
		messages.put(ResultConstant.RESULT, ResultConstant.SUCCESS);
		return messages;
	}

	/**
	 * 为用户添加角色
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/addRoleForUser", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map addRoleForUser(@RequestBody Map map) {
		Map messages = new HashMap();
		Integer user_id = (Integer) map.get(UserMsg.USER_ID);
		UserRole userRole = null;
		List<Map<String, Integer>> urList = (List<Map<String, Integer>>) map
				.get(UserRoleMsg.USER_ROLE);
		for (Map<String, Integer> urmap : urList) {
			userRole = new UserRole();
			Integer role_id = (Integer) urmap.get(RoleMsg.ROLE_ID);
			if (role_id != null) {
				userRole.setRoleId(role_id);
			}
			userRole.setUserId(user_id);
			userService.insertUserRole(userRole);
		}
		messages.put(ResultConstant.RESULT, ResultConstant.SUCCESS);
		return messages;
	}

	/**
	 * 用户登录
	 * @param map
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map login(@RequestBody Map map, HttpSession session) {
		Map messages = new HashMap();
		// 获取用户名或手机号码，密码
		String user_name = "";
		String username_or_tel = (String) map.get(UserMsg.USERNAME_OR_TEL);
		String user_password = (String) map.get(UserMsg.USER_PASSWORD);

		// 判空
		if (UserValidate.isNull(username_or_tel)) {
			messages.put(ResultConstant.RESULT,
					UserMsg.USERNAME_OR_TEL_NOT_NULL);
			return messages;
		}

		// 判空
		if (UserValidate.isNull(user_password)) {
			messages.put(ResultConstant.RESULT, UserMsg.PASSWORD_NOTNULL);
			return messages;
		}

		// 判断是否是手机号码
		if (UserValidate.isHandset(username_or_tel)) {// true为手机号码
			Map userDetailedMap = new HashMap();
			userDetailedMap.put(UserDetailedMsg.USER_TEL, username_or_tel);
			List<UserDetailed> userDetailedList = userService
					.getUserDetailedByCondition(userDetailedMap);
			if (userDetailedList.size() == 0) {// 该手机号码不存在
				messages.put(ResultConstant.RESULT,
						UserDetailedMsg.USER_TEL_NOT_EXIST);
				return messages;
			} else {
				User user = userService.findUserById(userDetailedList.get(0)
						.getUserId());
				user_name = user.getUserName();
			}

		} else {// false当做用户名
			user_name = username_or_tel;
		}

		// 用户登录认证
		Subject currentUser = SecurityUtils.getSubject();
		// if (!currentUser.isAuthenticated()) {
		// 把用户名和密码封装为 UsernamePasswordToken 对象
		UsernamePasswordToken token = new UsernamePasswordToken(user_name,
				user_password);
		// remember
		token.setRememberMe(true);
		try {
			currentUser.login(token);
		} catch (UnknownAccountException error) {
			messages.put(ResultConstant.RESULT, UserMsg.USER_NOT_EXIST);
			return messages;
		} catch (IncorrectCredentialsException incorrecterror) {
			messages.put(ResultConstant.RESULT, UserMsg.PASSWORD_ERROR);
			return messages;
		} catch (LockedAccountException lockerror) {
			messages.put(ResultConstant.RESULT, UserMsg.USER_BEENLOCKED);
		}
		// }
		// 获得用户基本信息
		User user = userService.getUserByUserName(user_name).get(0);
		UserDetailed userDetailed = userService
				.getUserDetailedByName(user_name);
		messages.put(ResultConstant.RESULT, ResultConstant.SUCCESS);
		messages.put("user", user);
		messages.put("user_detailed", userDetailed);

		// 记录该用户
		session.setAttribute(UserMsg.USER_NAME, user_name);
		return messages;
	}

	// 根据user_name或者user_id删除
	@RequestMapping(value = "/deleteUser", method = RequestMethod.DELETE, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map deleteByCondition(@RequestBody Map map) {
		Map messages = new HashMap();
		Integer user_id = (Integer) map.get(UserMsg.USER_ID);
		String user_name = (String) map.get(UserMsg.USER_NAME);
		if (!UserValidate.isNull(user_name)) {
			// List<User> userList = userService.getUserByUserName(user_name);
			// if (userList == null && userList.size() <= 0) {
			// messages.put(ResultConstant.RESULT, UserMsg.USER_NOT_EXIST);
			// return messages;
			// } else {
			user_id = userService.getUserIdByUsername(user_name);
			// }
		}
		// 删除用户基本信息
		userService.deleteUserById(user_id);

		// 删除用户详细信息
		userService.deleteUserDetailedById(user_id);

		// 删除用户角色
		userService.deleteUserRoleById(user_id);

		messages.put(ResultConstant.RESULT, ResultConstant.SUCCESS);
		return messages;
	}

	/**
	 * 修改用户民
	 * @param map
	 * @return
	 */
	/* @RequiresPermissions("user:update") */
	@RequestMapping(value = "/updateUserName", method = RequestMethod.PUT, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map updateUserName(@RequestBody Map map) {
		Map messages = new HashMap();
		// 获得用户修改条件
		String user_name = (String) map.get(UserMsg.USER_NAME);// 原用户名
		String update_user_name = (String) map.get(UserMsg.UPDATE_USER_NAME); // 修改后的用户名

		// 判断要进行修改的用户名是否为空
		if (UserValidate.isNull(update_user_name)) {
			messages.put(ResultConstant.RESULT,
					UserMsg.UPDATE_USER_NAME_NOTNULL);
			return messages;
		}

		// 判断要修改的用户名与原用户名是否相同
		if (update_user_name.equals(user_name)) {
			messages.put(ResultConstant.RESULT,
					UserMsg.ORIGINAL_AND_UPDATE_NAME_SAME);
			return messages;
		}

		// 判断要修改的用户名是否已经存在
		List<User> userList = userService.getUserByUserName(update_user_name);
		if (userList != null && userList.size() > 0) {// 用户已经存在
			messages.put(ResultConstant.RESULT, UserMsg.USER_EXIST);
			return messages;
		}

		// 进行用户修改
		User user = new User();
		user.setUserName(update_user_name);
		userService.updateUser(user, user_name);
		messages.put(ResultConstant.RESULT, ResultConstant.SUCCESS);
		return messages;
	}

	/**
	 *  修改密码
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/updateUserPassword", method = RequestMethod.PUT, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map updateUserPassword(@RequestBody Map map) {
		Map messages = new HashMap();
		String user_name = (String) map.get(UserMsg.USER_NAME);// 要修改密码的用户名
		String user_password = (String) map.get(UserMsg.USER_PASSWORD); // 原密码
		String update_user_password = (String) map
				.get(UserMsg.UPDATE_USER_PASSWORD); // 修改后的密码

		// 密码错误
		if (!userService.getPasswordByUserName(user_name).equals(
				EncryptionUtil.getEncryption(user_password, user_name, 1024))) {
			messages.put(ResultConstant.RESULT, UserMsg.PASSWORD_ERROR);
			return messages;
		}

		// 要修改的密码与原密码相同
		if (update_user_password.equals(user_password)) {
			messages.put(ResultConstant.RESULT,
					UserMsg.ORIGINAL_AND_UPDATE_PASSWORD_SAME);
			return messages;
		}

		// 密码格式错误(密码只能使用英文字母、数字以及-和_，并且首字符必须为字母或数字 密码首字符必须为字母或数字)
		if (!UserValidate.checkUserNamePassword(update_user_password)) {
			messages.put(ResultConstant.RESULT, UserMsg.PASSWORD_FORMAT_ERROR);
			return messages;
		}

		// 判断密码长度
		if (!UserValidate.isLengthRequired(UserMsg.PASSWORD_MIN_LENGTH,
				UserMsg.PASSWORD_MAX_LENGTH, update_user_password)) {
			messages.put(ResultConstant.RESULT, UserMsg.PASSWORD_LENGTH_ERROR);
			return messages;
		}

		// 封装要修改的用户密码
		User user = new User();
		user.setUserPassword(EncryptionUtil.getEncryption(update_user_password,
				user_name, 1024));// 密码加密
		userService.updateUser(user, user_name);

		messages.put(ResultConstant.RESULT, ResultConstant.SUCCESS);
		return messages;
	}

	/**
	 * 修改手机号码
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/updateUserTel", method = RequestMethod.PUT, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map updateUserTel(@RequestBody Map map) {
		Map messages = new HashMap();
		String user_name = (String) map.get(UserMsg.USER_NAME);// 要修改手机号码的用户名
		String update_user_tel = (String) map
				.get(UserDetailedMsg.UPDATE_USER_TEL);

		// 判断要修改的手机号码是否为空
		if (UserValidate.isNull(update_user_tel)) {
			messages.put(ResultConstant.RESULT,
					UserDetailedMsg.UPDATE_USER_TEL_NOTNULL);
			return messages;
		}

		// 判断手机号是否被注册
		Map userTelConditionMap = new HashMap();
		userTelConditionMap.put(UserDetailedMsg.USER_TEL, update_user_tel);
		List<UserDetailed> userDetaileds = userService
				.getUserDetailedByCondition(userTelConditionMap);
		if (userDetaileds.size() > 0) {
			// 判断被注册的手机号是不是该用户的
			UserDetailed userDetailed = userService
					.getUserDetailedByName(user_name);
			if (userDetailed.getUserTel().equals(update_user_tel)) {
				messages.put(ResultConstant.RESULT,
						UserDetailedMsg.ORIGINAL_AND_UPDATE_TEL_SAME);
			} else {
				messages.put(ResultConstant.RESULT,
						UserDetailedMsg.USER_TEL_EXIST);
			}
			return messages;
		}

		// 手机号码格式不正确
		if (!UserValidate.isHandset(update_user_tel)) {
			messages.put(ResultConstant.RESULT,
					UserDetailedMsg.TEL_FORMAT_ERROR);
			return messages;
		}

		UserDetailed userDetailed = new UserDetailed();
		userDetailed.setUserTel(update_user_tel);
		userService.updateUserTel(userDetailed, user_name);
		messages.put(ResultConstant.RESULT, ResultConstant.SUCCESS);
		return messages;
	}

	/**
	 * 获取所有用户信息
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/getPageInfo", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public PageResult<User> getPageInfo(HttpServletRequest request) {
		int currentPage = Integer.parseInt((String) request
				.getParameter(PageInfoMsg.CURRENT_PAGE));
		int pageSize = Integer.parseInt((String) request
				.getParameter(PageInfoMsg.PAGE_SIZE));
		PageInfo pageInfo = userService.getPageInfo(currentPage, pageSize);
		PageResult<User> pageResult = new PageResult<User>(currentPage,
				pageSize, (int) pageInfo.getTotal());
		pageResult.setRows(pageInfo.getList());
		return pageResult;
	}

	/**
	 *	通过用户名查询单个用户
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/getUserByUserName", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map getUserByUserName(@RequestParam String user_name) {
		Map messages = new HashMap();
		List<User> userList = userService.getUserByUserName(user_name);
		if (userList.size() == 0) {
			messages.put(ResultConstant.RESULT, UserMsg.USER_NOT_EXIST);
			return messages;
		}
		messages.put(ResultConstant.RESULT, userList.get(0));
		return messages;
	}
}
